﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GISCore.Geometry;
using GISCore.Geometry.IO;

namespace GISTools.Generators
{
    internal class ShiftMapGenerator : IMapGenerator
    {
        private Layer Map { get; set; }
        private double Shift { get; set; }

        internal ShiftMapGenerator(Layer seed, double percentageShift)
        {
            Map = seed;
        }

        public Layer Generate()
        {
            var polygons = new List<Polygon>();
            var origs = from poly in Map.GetPolygons()
                        select poly;

            double dx = Shift;
            double dy = Shift;
            
            foreach (var poly in origs)
            {
                polygons.Add(_shiftPolygon(poly, dx, dy));
            }
            
            var newLayer = new Layer(0, polygons);

            Point oldLower = Map.GetBoundingBox()[0];
            Point oldUpper = Map.GetBoundingBox()[1];
            Point upper = new Point(oldUpper.X * dx, oldUpper.Y * dy);

            newLayer.SetBoundingBox(oldLower, upper);

            return newLayer;
        }

        private Polygon _shiftPolygon(Polygon p, double dx, double dy)
        {
            Point delta = new Point(dx, dy);
            // map all the lines in the polygon p
            // to new lines shifted by the delta x and delta y
            var lines = from line in p.getLines()
                        where line != null
                        select new Line(line.Start + delta, line.End + delta);

            var holes = from hole in p.holes
                        where hole != null
                        select new Hole(0, (
                            from line in hole.getLines()
                            where line != null
                            select new Line(line.Start + delta, line.End + delta)).ToList());

            var newPoly = new Polygon(0, lines.ToList());
            newPoly.holes = holes.ToList();

            return newPoly;
        }
    }
}
